package com.yueqian.system.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yueqian.framework.entity.BaseEntity;
import com.yueqian.system.converter.RoleConvert;
import com.yueqian.system.entity.Menu;
import com.yueqian.system.entity.Role;
import com.yueqian.system.entity.RoleMenu;
import com.yueqian.system.mapper.RoleMapper;
import com.yueqian.system.service.RoleMenuService;
import com.yueqian.system.service.RoleService;
import com.yueqian.system.vo.req.MenuReqVO;
import com.yueqian.system.vo.req.RoleReqVO;
import com.yueqian.system.vo.res.MenuResVO;
import com.yueqian.system.vo.res.RoleResVO;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;


@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

	@Resource
	private RoleMenuService roleMenuService;


	@Resource
	private MenuServiceImpl menuService;







	@Override
	public IPage<RoleResVO> selectPageData(RoleReqVO reqVO) {
		Page<Role> roleIPage = (Page<Role>) this.baseMapper.selectPage(reqVO.getPage(reqVO.getCurrentPage(), reqVO.getPageSize()), Wrappers.lambdaQuery(Role.class)
																																		   .like(StrUtil.isNotBlank(reqVO.getName()), Role::getName, reqVO.getName())
																																		   .eq(ObjectUtil.isNotEmpty(reqVO.getStatus()), Role::getStatus, reqVO.getStatus())
																																		   .orderByAsc(Role::getSort)
																																		   .orderByDesc(BaseEntity::getCreatorTime));
		return RoleConvert.INSTANCE.toPage(roleIPage);
	}


	@Override
	public void editStatus(RoleReqVO reqVO) {
		Role role = RoleConvert.INSTANCE.toEntity(reqVO);
		if (ObjectUtil.isEmpty(this.getById(role.getId()))) {
			throw new RuntimeException("角色不存在");
		}
		this.updateById(role);
	}

	@Override
	public RoleResVO getDetail(Long id) {
		MenuReqVO reqVO = new MenuReqVO();
		List<MenuResVO> menus = menuService.getMenus(reqVO);
		Role role = this.baseMapper.selectById(id);
		if (ObjectUtil.isEmpty(role)) {
			role = new Role();
			RoleResVO roleResVO = RoleConvert.INSTANCE.toRes(role);
			roleResVO.setMenuOptions(menus);
			return roleResVO;
		}
		RoleResVO roleResVO = RoleConvert.INSTANCE.toRes(role);
		List<Long> menuIds = roleMenuService.list(Wrappers.lambdaQuery(RoleMenu.class).eq(RoleMenu::getRoleId, id)).stream().map(RoleMenu::getMenuId).sorted().collect(Collectors.toList());
		roleResVO.setMenuIds(menuIds);
		roleResVO.setMenuOptions(menus);
		return roleResVO;
	}


	@Transactional
	@Override
	public Long add(RoleReqVO reqVO) {
		Role role = RoleConvert.INSTANCE.toEntity(reqVO);
		this.saveOrUpdate(role);
		roleMenuService.remove(Wrappers.lambdaQuery(RoleMenu.class).eq(RoleMenu::getRoleId, role.getId()));
			reqVO.getMenuIds().forEach(id -> {
				RoleMenu roleMenu = new RoleMenu();
				Menu menu = menuService.getById(id);
				ArrayList<Long> menuParentIds = new ArrayList<>();
				//获取菜单父节点id数据
				menuService.getParentMenuIds(menu.getParentId(), menuParentIds);
				if (CollectionUtil.isEmpty(menuParentIds)) {
					menuParentIds.add(0L);
				}
				for (Long menuParentId : menuParentIds) {
					roleMenu.setMenuParentId(menuParentId);
					roleMenu.setRoleId(role.getId());
					roleMenu.setMenuId(id);
					roleMenuService.saveOrUpdate(roleMenu);
				}
			});
		return reqVO.getId();
	}

	@Override
	public Long delete(Long id) {
		if (ObjectUtil.isEmpty(this.getById(id))) {
			throw new RuntimeException("角色数据不存在");
		}
		this.removeById(id);
		return id;
	}

	@Override
	public List<RoleResVO> getRoleType() {
		List<Role> list = this.list();
		return RoleConvert.INSTANCE.toResList(list);
	}

	@Override
	public List<Role> selectListData(RoleReqVO reqVO) {
		return this.list();
	}
}
